package maMetrics;

import java.util.ArrayList;
import java.util.Iterator;

import maConfigration.MetricSettings;
import maUtil.LogFile;
import maUtil.RecordUnit;
import maUtil.SortedRecords;

import com.telelogic.rhapsody.core.IRPAttribute;
import com.telelogic.rhapsody.core.IRPClass;
import com.telelogic.rhapsody.core.IRPCollection;
import com.telelogic.rhapsody.core.IRPInterfaceItem;
import com.telelogic.rhapsody.core.IRPOperation;
import com.telelogic.rhapsody.core.IRPPackage;
import com.telelogic.rhapsody.core.IRPProject;

public class MetricNOD extends MetricObject {
	
	SortedRecords _srProj = null;
	SortedRecords _srPkg = null;
	LogFile _logFile = null;
	
	//csv variables
	LogFile _csvLogFileProj = null;
	SortedRecords _srProjCsv = null;
	protected LogFile _logRawData = null;
	
	int _nSum;
	
	private ArrayList<IRPClass> _listOfNOD = new ArrayList<IRPClass>();
	
	/* NOD = Number Of Descendants, it count all the children and their children etc. to a class*/
//	public MetricNOD() {
//		// TODO booleans is to be generated from configure file
//		_sMetricName = "Metric: Number Of Decendants";
//		
//		_isApplyToProj = true;
//		_isApplyToCls = true;
//		
//		_logFile = new LogFile("MetricNOD.txt");
//		_nSum = 0;
//		_iWeight = 1;
//	}
	
	public MetricNOD (MetricSettings ms)
	{
		super(ms);

		_sMetricName = "Metric: Number Of Decendants";
		if(_isApplyToPkg)
		{
			_srPkg = new SortedRecords(2000, _sMetricName + " Sorted By Packages");
		}
		if(_isApplyToProj)
		{
			_srProj = new SortedRecords(2000, _sMetricName + " Sorted By Packages");
			_srProjCsv = new SortedRecords(10, "NOD,Class");
		}
		_logFile = new LogFile("MetricNOD.txt");
		
		if(_isLogRawData)
		{
			_logRawData = new LogFile("MetricNODRawData.csv");
			_logRawData.logLn("Value,Classname");
		}
		
		_nSum = 0;
	}
	
	private int countNOD(IRPClass cls) 
	{
		getNODRecursively(cls);
		return _listOfNOD.size();
	}
	
	/* Recursively loops through all paths from the class down, also check that the class does
	 * not already exists */
	private void getNODRecursively(IRPClass cls)
	{
		Iterator itr = cls.getDerivedClassifiers().toList().iterator();
		while(itr.hasNext())
		{
			Object obj = itr.next();
			if(obj instanceof IRPClass)
			{
				IRPClass derivedCls = (IRPClass) obj;
				if(!_listOfNOD.contains(derivedCls))
					_listOfNOD.add(derivedCls);
				getNODRecursively(derivedCls);
			}
			
		}
	}

	private void log(String str) {
		_logFile.log(str);
	}
	
	@Override
	public int applyInProj(IRPProject proj) {
		// TODO Auto-generated method stub
		/*_csvLogFileProj = new LogFile("MetricNOD"+ proj.getName() +".csv");
		if(!_isApplyToProj)
			return 0;
		if(_srProjCsv.getSize() > 0)
		{
			_csvLogFileProj.logLn("NOD,Class");
			_csvLogFileProj.logPln(_srProjCsv.getAllStringCSV());
		}
		//_csvLogFileProj = new LogFile("MetricDIT"+ proj.getName().toUpperCase() +".csv");
		_srProjCsv = new SortedRecords(10, "NOD,Class");*/
		
		int n = _nSum;
		_nSum = 0;
		return n;
	}

	@Override
	public int applyInPkg(IRPPackage pkg) {
		// TODO Auto-generated method stub
		/*if(!_isApplyToPkg)
		{
			return 0;
		}
		if(_srPkg != null)
		{
			log(_srPkg.getAllString());
		}
		_srPkg = new SortedRecords(20, _sMetricName);*/
		return 0;
	}

	@Override
	public int applyInCls(IRPClass cls) {
		// TODO Auto-generated method stub
		_listOfNOD.clear();
		if(_srProj == null)
			_srProj = new SortedRecords(2000, _sMetricName + " " + cls.getProject().getName());
		int n = countNOD(cls);
		RecordUnit ru = new RecordUnit(n, cls.getFullPathNameIn());
		if(_isApplyToProj && n > 0) //_srProj.getMinValue())
		{
			_srProj.add(ru);
		}
		if(_isApplyToProj && n >= _srProjCsv.getMinValue())	
			_srProjCsv.add(new RecordUnit(n, cls.getName()));
		_nSum += n;
		
		if(_isLogRawData && n>0) 
			_logRawData.logLn(n + "," + cls.getFullPathNameIn());
		
		return n;
	}

	@Override
	public int applyInItf(IRPInterfaceItem itf) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int applyInOp(IRPOperation op) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int applyInAttr(IRPAttribute attrb) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void finish() {
		if(_srProj != null) log(_srProj.getAllString());
	}


}
